package com.xunsiya.service.module.device.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xunsiya.common.config.RequestUtils;
import com.xunsiya.common.config.util.ConstantInfo;
import com.xunsiya.common.config.util.HttpClientUtil;
import com.xunsiya.common.config.util.Md5Util;
import com.xunsiya.module.device.dao.DeviceMapper;
import com.xunsiya.module.device.dao.VideoStreamCompanyMapper;
import com.xunsiya.module.device.vo.Device;
import com.xunsiya.service.module.device.DeviceService;
import com.xunsiya.system.dao.CompanyMapper;
import com.xunsiya.system.vo.Company;
import com.xunsiya.system.vo.User;
import com.xunsiya.tools.common.msg.Msg;
import com.xunsiya.tools.common.pagination.PagedUtil;
import com.xunsiya.tools.common.string.StringUtil;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import com.xunsiya.tools.common.pagination.ForePage;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

/**
 * 设备管理实现类，主要实现设备的新增、修改、删除等操作
 *
 * @author jiax
 * @version 1.0
 */
@Service
public class DeviceServiceImpl implements DeviceService {

    /**
     * 设备待激活状态
     */
    private static final String DEVICE_AVIABLE = "2";

    /**
     * 设备删除状态
     */
    private static final String DEVICE_DELETE = "0";

    /**
     * 设备激活状态
     */
    private static final String DEVICE_ACTIVE = "1";

    /**
     * 远程删除设备紫万返回的删除成功结果
     */
    private static final String RETURN_SUCCESS = "success";

    /**
     * 新增设备初始化parentId
     */
    private static final Integer INIT_PARENT_ID = 0;

    /**
     * 新增设备初始化平台id
     */
    private static final Integer INIT_PLANTFORM_ID = 0;

    /**
     * 激活以后设备的数量
     */
    private static final Integer ACTIVATION_COUNT = 4;

    /**
     * 激活请求响应码
     */
    private static final Integer STATUS_CODE = 400;

    /**
     * 日志输出
     */
    private final Logger log = Logger.getLogger(DeviceServiceImpl.class);

    @Autowired
    private DeviceMapper deviceMapper;

    @Autowired
    private VideoStreamCompanyMapper videostreamCompanyMapper;

    @Autowired
    private CompanyMapper companyMapper;

    @Value("${path.zwan-url}")
    private String zwUrl;

    @Value("${path.zwan-name}")
    private String loginName;

    @Value("${path.zwan-password}")
    private String loginPass;

    @Value("${path.devicetype}")
    private String devicetype;

    @Value("${path.devicevendorid}")
    private String devicevendorid;

    /**
     * 获取紫万账号和密码
     *
     * @param device
     * @return
     */
    private Device getZwInfo(Device device) {
        //配置紫万请求参数
        HashMap<String, Object> map = new HashMap<>(8);
        Company company = deviceMapper.queryCompanyInfoById(device.getCompanyId());
        StringBuilder companyId = new StringBuilder();
        StringBuilder companyPsd = new StringBuilder();

        if (company.getZwId() != null && company.getZwPassword() != null) {
            companyId.append(company.getZwId());
            companyPsd.append(company.getZwPassword());
        }
        if (company.getZwId() == null || company.getZwPassword() == null) {
            HashMap<String, Object> companyMap = new HashMap<>(8);
            companyMap.put("loginname", loginName);
            companyMap.put("loginpass", loginPass);
            companyMap.put("name", company.getCompanyName());
            companyMap.put("contact", company.getContact());
            companyMap.put("phoneno", company.getPhone());
            companyMap.put("email", company.getEmail());
            String companyResult = HttpClientUtil.getZwanPostResult(zwUrl + "zwgw/createcompany", companyMap);
            log.info("result = " + companyResult);
            if (null != companyResult) {
                JSONObject json = JSON.parseObject(companyResult);
                if (RETURN_SUCCESS.equals(json.getString("result"))) {
                    company.setZwId(json.getInteger("companyid"));
                    company.setZwPassword(json.getString("password"));
                    companyId.append(json.getInteger("companyid"));
                    companyPsd.append(json.getString("password"));
                    deviceMapper.updateCompanyInfo(company);
                }
            }
        }

        map.put("companyid", companyId.toString());
        //设备蓝牙地址
        map.put("deviceid", device.getGuid());
        map.put("devicetype", devicetype);
        map.put("devicevendorid", devicevendorid);

        StringBuffer sb = new StringBuffer();
        sb.append("companyid=").append(companyId.toString()).append("&deviceid=").append(map.get("deviceid")).append("&devicetype=").append(devicetype).append("&devicevendorid=").append(devicevendorid);
        sb = new StringBuffer(Md5Util.getMd5("MD5", 0, null, sb.toString()));
        sb.append(companyPsd.toString());
        String digest = Md5Util.getMd5("MD5", 0, null, sb.toString());
        map.put("digest", digest);
        //发送紫万请求，并解析请求结果
        String result = HttpClientUtil.getZwanPostResult(zwUrl + "zwgw/createdevice", map);
        log.info("结果：" + result);
        if (!StringUtil.isEmpty(result)) {
            JSONObject json = JSON.parseObject(result);
            String remoteNo = json.getString("zwannumber");
            String pwd = json.getString("password");
            Integer statusCode = json.getInteger("status");
            if(statusCode != null){
                device.setRequestStatus(statusCode);
            }
            if (!"".equals(remoteNo) && remoteNo != null) {
                device.setZwanNumber(remoteNo);
                device.setZwanPassword(pwd);
            }
        }else{
            device.setRequestStatus(STATUS_CODE);
        }
        return device;
    }

    /**
     * 远程删除设备信息
     *
     * @param device 设备信息
     * @return
     */
    private boolean removeDeviceFromZw(Device device) {
        boolean bool = false;
        //配置紫万请求参数
        HashMap<String, Object> map = new HashMap<>(8);
        Company company = deviceMapper.queryCompanyInfoById(device.getCompanyId());
        String companyId = company.getZwId().toString();
        String companyPsd = company.getZwPassword();
        map.put("companyid", companyId);
        //设备蓝牙地址
        map.put("deviceid", device.getGuid());
        map.put("devicenumber", device.getZwanNumber());

        StringBuffer sb = new StringBuffer();
        sb.append("companyid=").append(companyId).append("&deviceid=").append(map.get("deviceid")).append("&devicenumber=").append(map.get("devicenumber"));
        sb = new StringBuffer(Md5Util.getMd5("MD5", 0, null, sb.toString()));
        sb.append(companyPsd);
        String digest = Md5Util.getMd5("MD5", 0, null, sb.toString());
        map.put("digest", digest);
        //发送紫万请求，并解析请求结果
        String result = HttpClientUtil.getZwanPostResult(zwUrl + "zwgw/removedevice", map);
        log.info("结果：" + result);
        if (!"".equals(result)) {
            JSONObject json = JSON.parseObject(result);
            String sucess = json.getString("result");
            if (RETURN_SUCCESS.equals(sucess)) {
                bool = true;
            }
        }
        return bool;
    }

    /**
     * 添加设备信息
     *
     * @param device 设备信息
     * @return
     */
    @Override
    public Msg saveDevice(Device device) {

        User user = RequestUtils.getSessionAttribte(User.SYS_LOGIN_INFO);
        Msg msg = new Msg(false);
        //验证id，判断是更新还是新增
        if (device.getId() == null) {
            if (!ConstantInfo.PLATFORM_COPMANY_ID.equals(user.getCompanyId())) {
                if (device.getCheckCode() == null) {
                    msg.setMsg("激活码不能为空！");
                    return msg;
                }
                String codeMD5 = Md5Util.getMd5("MD5", 0, "UTF-8", device.getGuid());
                if (!device.getCheckCode().equals(codeMD5.substring(26))) {
                    msg.setMsg("激活码与设备不匹配，请重试！");
                    return msg;
                }
            }
            boolean bool = false;
            //根据蓝牙地址去重
            Device oldDevice = deviceMapper.queryByGuid(device.getGuid());
            if (oldDevice != null && !DEVICE_DELETE.equals(oldDevice.getStatus())) {
                msg.setMsg("新增设备信息失败：设备名称已存在！");
                return msg;
            }
            Device newDevice = new Device();
            newDevice.setGuid(device.getGuid());
            if (device.getCompanyId() == null) {
                newDevice.setCompanyId(user.getCompanyId());
            } else {
                newDevice.setCompanyId(device.getCompanyId());
            }
            //增加其他字段信息
            newDevice.setStatus(DEVICE_AVIABLE);
            newDevice.setCreateTime(new Date());
            newDevice.setUpdateTime(new Date());
            newDevice.setCreateBy(user.getId());
            newDevice.setUpdateBy(user.getId());
            newDevice.setParentId(INIT_PARENT_ID);
            newDevice.setPlantformId(INIT_PLANTFORM_ID);
            newDevice.setUserId(device.getUserId());


            if (oldDevice != null && DEVICE_DELETE.equals(oldDevice.getStatus())) {
                //查询其他终端设备
                List<Device> otherDevices = deviceMapper.findOtherDevice(oldDevice.getId());
                for(Device d: otherDevices){
                    d.setStatus(DEVICE_AVIABLE);
                    d.setUpdateBy(user.getId());
                    d.setCreateBy(user.getId());
                    d.setCreateTime(new Date());
                    d.setUpdateTime(new Date());
                    d.setUserId(device.getUserId());
                    deviceMapper.updateDevice(d);
                }
                newDevice.setId(oldDevice.getId());
                bool = deviceMapper.updateDevice(newDevice);
            } else {
                bool = deviceMapper.saveDevice(newDevice);
            }

            return new Msg(bool, bool ? "新增设备信息成功！" : "新增设备信息失败！");
        } else {
            //更新表
            device.setUpdateBy(user.getId());
            boolean bool = deviceMapper.updateDevice(device);
            return new Msg(bool, bool ? "更新设备信息成功！" : "更新设备信息失败！");
        }

    }

    /**
     * 根据紫万账号删除对应的时长
     *
     * @param zwNumber 蓝牙设备地址
     * @return
     */
    @Override
    public boolean deleteSpendTime(String zwNumber) {
        return deviceMapper.deleteSpendTime(zwNumber);
    }

    /**
     * 根据设备id查询相关记录
     *
     * @param id 设备id
     * @return
     */
    @Override
    public List<Device> queryDeviceById(Integer id) {
        return deviceMapper.queryDeviceById(id);
    }

    /**
     * 根据id删除设备
     *
     * @param id 设备id
     * @return
     */
    @Override
    public boolean deleteDevice(Integer id) {
        boolean bool = false;
        List<Device> devices = queryDeviceById(id);
        for(Device device: devices){
            if (device.getZwanNumber() == null) {
                return deviceMapper.deleteDevice(id);
            }
            //请求紫万删除该蓝牙设备
            if (!removeDeviceFromZw(device)) {
                log.info("远程删除设备失败！");
                return bool;
            }
        }
        // 时长记录不删除，更改设备状态为0
        bool = deviceMapper.deleteDevice(id);
        return bool;
    }

    /**
     * 分页查询设备信息
     *
     * @param device    设备信息
     * @param pageIndex 页码位置
     * @param pageSize  每页数量
     * @return
     */
    @Override
    public ForePage<Device> findPage(Device device, int pageIndex, int pageSize) {

        User user = RequestUtils.getSessionAttribte(User.SYS_LOGIN_INFO);
        List<Company> companies = null;
        if (device.getCompanyId() == null) {
            if (ConstantInfo.PLATFORM_COPMANY_ID.equals(user.getCompanyId())) {
                companies = deviceMapper.findAllSubCompany();
            } else {
                companies = deviceMapper.findSubCompany(user.getCompanyId());
            }
        } else {
            companies = deviceMapper.findSubCompany(device.getCompanyId());
        }
        List<Integer> companyIds = new ArrayList<>();
        for (Company co : companies) {
            companyIds.add(co.getId());
        }
        device.setCompanyIds(companyIds);
        int count = deviceMapper.queryCount(device);
        List<Device> list = deviceMapper.queryForPage(device, PagedUtil.getStartIndex(pageIndex, pageSize), pageSize);
        // 循环获取设备使用时长
        for (Device dev : list) {
            if (dev.getZwanNumber() != null) {
                Integer spendTime = deviceMapper.querySpendTime(dev.getZwanNumber());
                dev.setSpendTime(spendTime);
            }
            if (dev.getUserId() != null) {
                String userName = deviceMapper.queryUserName(dev.getUserId());
                if (userName != null) {
                    dev.setUserName(userName);
                }
            }
        }
        return new ForePage<>(count, pageIndex, list);

    }

    @Override
    public ForePage<Device> findAll(Device device, int pageIndex, int pageSize) {
        // 当前用户
        User user = RequestUtils.getSessionAttribte(User.SYS_LOGIN_INFO);
        // 查询所有子级
        if (!ConstantInfo.PLATFORM_COPMANY_ID.equals(user.getCompanyId())) {
            List<Company> companyList = companyMapper.getCompanyByUser(user.getCompanyId());
            List<Integer> ids = new ArrayList<>();
            for (Company e : companyList) {
                ids.add(e.getId());
            }
            device.setCompanyIds(ids);
        }

        int count = deviceMapper.queryCount(device);
        List<Device> list = deviceMapper.queryForPage(device, PagedUtil.getStartIndex(pageIndex, pageSize), pageSize);
        // 循环获取设备使用时长
        for (Device dev : list) {
            Integer spendTime = deviceMapper.querySpendTime(dev.getZwanNumber());
            dev.setSpendTime(spendTime);
        }
        return new ForePage<>(count, pageIndex, list);
    }

    /**
     * 获取企业id
     *
     * @param deviceId 设备编号
     * @return
     */
    @Override
    public Integer getDeviceId(String deviceId) {
        // 根据蓝牙地址查询设备信息
        Device device = deviceMapper.findByGuid(deviceId);
        if (device == null) {
            log.info("设备信息不存在");
            return null;
        }
        // 人脸识别
        return device.getCompanyId();
    }

    /**
     * 激活设备
     *
     * @param device 设备
     * @return
     */
    @Override
    public Msg activation(Device device) {
        User user = RequestUtils.getSessionAttribte(User.SYS_LOGIN_INFO);
        List<Device> allDevices = new ArrayList<>();
        Integer id = device.getId();
        Integer userId = device.getUserId();
        device.setStatus(DEVICE_ACTIVE);
        allDevices.add(device);
        for (int i = 1; i < 4; i++) {
            Device newDevice = new Device();
            newDevice.setId(null);
            newDevice.setGuid(device.getGuid() + i);
            newDevice.setPlantformId(i);
            newDevice.setParentId(id);
            newDevice.setUserId(userId);
            newDevice.setCompanyId(device.getCompanyId());
            newDevice.setResolution(device.getResolution());
            newDevice.setExpireTime(device.getExpireTime());
            newDevice.setStatus(DEVICE_ACTIVE);
            newDevice.setCreateBy(user.getId());
            newDevice.setUpdateBy(user.getId());
            newDevice.setCreateTime(new Date());
            newDevice.setUpdateTime(new Date());
            allDevices.add(newDevice);
        }
        for (Device dev : allDevices) {
            dev = getZwInfo(dev);
        }
        for (Device dev : allDevices) {
            if(STATUS_CODE.equals(dev.getRequestStatus())){
                return new Msg(false, "平台已激活过此设备，请联系平台处理后重新操作！");
            }
            if (dev.getId() != null && dev.getZwanNumber() != null) {
                deviceMapper.updateDevice(dev);
            } else if (dev.getId() == null && dev.getZwanNumber() != null) {
                deviceMapper.saveDevice(dev);
            } else {
                return new Msg(false, "设备激活失败！");
            }
        }
        Integer deviceCount = deviceMapper.queryDeviceCount(device);
        return  new Msg(ACTIVATION_COUNT.equals(deviceCount),  ACTIVATION_COUNT.equals(deviceCount) ? "设备激活成功！": "设备激活失败！");
    }

    /**
     * 查询绑定的用户
     *
     * @param device 设备
     * @return
     */
    @Override
    public List<User> findBindUsers(Device device) {
        //获取用户登录信息
        User user = RequestUtils.getSessionAttribte(User.SYS_LOGIN_INFO);
        List<Company> companies = new ArrayList<>();
        ;
        Integer companyId = device.getCompanyId();
        if (companyId == null) {
            //初始化数据
            if (ConstantInfo.PLATFORM_COPMANY_ID.equals(user.getCompanyId())) {
                //超级管理员获取所有用户
                companies.addAll(deviceMapper.findAllSubCompany());
            } else {
                //根据companyId的获取所有子公司使用者
                if ("query".equals(device.getUserName())) {
                    companies.addAll(deviceMapper.findSubCompany(user.getCompanyId()));
                } else {
                    companies.add(deviceMapper.queryCompanyInfoById(user.getCompanyId()));
                }

            }
        } else {
            //依据companyId查询的所有使用者
            if ("query".equals(device.getUserName())) {
                companies.addAll(deviceMapper.findSubCompany(companyId));
            } else {
                companies.add(deviceMapper.queryCompanyInfoById(companyId));
            }

        }
        List<User> users = new ArrayList<>();
        for (Company co : companies) {
            List<User> deviceUsers = new ArrayList<>();
            if ("query".equals(device.getUserName())) {
                deviceUsers.addAll(deviceMapper.findAllUsers(co.getId()));
            } else {
                deviceUsers.addAll(deviceMapper.findBindUsers(co.getId()));
            }
            users.addAll(deviceUsers);
        }
        return users;
    }

    @Override
    public List<Device> queryAllTypesDevice(Device device) {
        List<Device> devices = deviceMapper.queryAllTypesDevice(device);
        for (Device dev : devices) {
            if (dev.getZwanNumber() != null) {
                dev.setSpendTime(deviceMapper.querySpendTime(dev.getZwanNumber()));
            }
            if (dev.getUserId() != null) {
                dev.setUserName(deviceMapper.queryUserName(dev.getUserId()));
            }
        }
        return devices;
    }

    @Override
    public List<Company> findSubCompany(Device device) {
        User user = RequestUtils.getSessionAttribte(User.SYS_LOGIN_INFO);
        if (device.getCompanyId() == null) {
            if (ConstantInfo.PLATFORM_COPMANY_ID.equals(user.getCompanyId())) {
                return deviceMapper.findAllSubCompany();
            } else {
                return deviceMapper.findSubCompany(user.getCompanyId());
            }
        } else {
            return deviceMapper.findSubCompany(device.getCompanyId());
        }
    }

    @Override
    public Integer findPlantformId() {
        User user = RequestUtils.getSessionAttribte(User.SYS_LOGIN_INFO);
        return user.getCompanyId();
    }

    @Override
    public String getRealName() {
        User user = RequestUtils.getSessionAttribte(User.SYS_LOGIN_INFO);
        return user.getRealName();
    }

}
